/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package io.renren.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.Constant;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.product.entity.ProductUserEntity;
import io.renren.modules.product.service.ProductUserService;
import io.renren.modules.sys.dao.SysUserDao;
import io.renren.modules.sys.entity.SysRoleEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.SysUserRoleEntity;
import io.renren.modules.sys.service.SysRoleService;
import io.renren.modules.sys.service.SysUserRoleService;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.sys.vo.DeveloperVo;
import io.renren.modules.sys.vo.EmployeeVo;
import io.renren.modules.sys.vo.TesterVo;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
	@Autowired
	private SysUserRoleService sysUserRoleService;
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	@Lazy
	private ProductUserService productUserService;
	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String username = (String)params.get("username");
		Long createUserId = (Long)params.get("createUserId");

		IPage<SysUserEntity> page = this.page(
			new Query<SysUserEntity>().getPage(params),
			new QueryWrapper<SysUserEntity>()
				.like(StringUtils.isNotBlank(username),"username", username)
				.eq(createUserId != null,"create_user_id", createUserId)
		);

		return new PageUtils(page);
	}

	@Override
	public List<DeveloperVo> getProductDeveloper(Long productId) {
		//获取该产品下所有的成员
		List<ProductUserEntity> productUserEntityList = productUserService.getUserByProductId(productId);
		List<Long> productUserId = productUserEntityList.stream().map(productUserEntity -> productUserEntity.getUserId())
				.collect(Collectors.toList());
		//获取所有的开发者
		// 开发角色id
		SysRoleEntity roleEntity = sysRoleService.getOne(new QueryWrapper<SysRoleEntity>().eq("role_name", "开发人员"));
		// 1. 查询出所有开发人员id
		QueryWrapper<SysUserRoleEntity> wrapper = new QueryWrapper<>();
		wrapper.eq("role_id",roleEntity.getRoleId());
		List<SysUserRoleEntity> sysUserRoleEntities = sysUserRoleService.list(wrapper);
		// 收集开发人员id
		List<Long> userIds = sysUserRoleEntities.stream().map(sysUserRoleEntity -> {
			return sysUserRoleEntity.getUserId();
		}).collect(Collectors.toList());
		// 查询出所有开发人员信息
		List<SysUserEntity> sysUserEntities = this.listByIds(userIds);
		// 封装程vo
		List<DeveloperVo> developerVos = sysUserEntities.stream().map(sysUserEntity -> {
			DeveloperVo developerVo = new DeveloperVo();
			BeanUtils.copyProperties(sysUserEntity, developerVo);
			return developerVo;
		}).collect(Collectors.toList());
		//筛选出该产品下的开发者
		List<DeveloperVo> list = developerVos.stream().filter(developerVo -> productUserId.contains(developerVo.getUserId()))
				.collect(Collectors.toList());
		return list;
	}
	@Override
	public List<TesterVo> getProductTester(Long productId) {
		//获取该产品下所有的成员
		List<ProductUserEntity> productUserEntityList = productUserService.getUserByProductId(productId);
		List<Long> productUserIds = productUserEntityList.stream().map(productUserEntity -> productUserEntity.getUserId())
				.collect(Collectors.toList());

		//获取所有的测试人员
		// 测试角色id
		SysRoleEntity roleEntity = sysRoleService.getOne(new QueryWrapper<SysRoleEntity>().eq("role_name", "测试人员"));
		// 1. 查询出所有测试人员id
		QueryWrapper<SysUserRoleEntity> wrapper = new QueryWrapper<>();
		wrapper.eq("role_id",roleEntity.getRoleId());
		List<SysUserRoleEntity> sysUserRoleEntities = sysUserRoleService.list(wrapper);
		List<Long> userIds = sysUserRoleEntities.stream().map(sysUserRoleEntity -> {
			return sysUserRoleEntity.getUserId();
		}).collect(Collectors.toList());
		List<SysUserEntity> sysUserEntities = this.listByIds(userIds);
		// 封装程vo
		List<TesterVo> testerVos = sysUserEntities.stream().map(sysUserEntity -> {
			TesterVo testVo = new TesterVo();
			BeanUtils.copyProperties(sysUserEntity, testVo);
			return testVo;
		}).collect(Collectors.toList());

		//筛选出在该团队中存在的测试人员
		List<TesterVo> list = testerVos.stream().filter(testerVo -> productUserIds.contains(testerVo.getUserId()))
				.collect(Collectors.toList());
		return list;
	}

    @Override
    public List<SysUserEntity> getTestUser() {
		List<SysUserRoleEntity> sysUserRoleList = sysUserRoleService.list(new QueryWrapper<SysUserRoleEntity>().eq("role_id", 4L));
		ArrayList<Long> ids = new ArrayList<>();
		for (SysUserRoleEntity sysUserRoleEntity : sysUserRoleList) {
			ids.add(sysUserRoleEntity.getUserId());
		}
		List<SysUserEntity> sysUserList = this.listByIds(ids);
		return sysUserList;
    }

    @Override
	public SysUserEntity findAllMoudle(Long userIds) {
		QueryWrapper<SysUserEntity> sysUserEntityQueryWrapper = new QueryWrapper<>();
		sysUserEntityQueryWrapper.eq("user_id",userIds);
		SysUserEntity sysUserEntity = baseMapper.selectOne(sysUserEntityQueryWrapper);
		return sysUserEntity;
	}



	@Override
	public List<Long> queryAllMenuId(Long userId) {
		return baseMapper.queryAllMenuId(userId);
	}

	@Override
	public SysUserEntity queryByUserName(String username) {
		return baseMapper.queryByUserName(username);
	}

	@Override
	@Transactional
	public void saveUser(SysUserEntity user) {
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
		user.setSalt(salt);
		this.save(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	@Transactional
	public void update(SysUserEntity user) {
		if(StringUtils.isBlank(user.getPassword())){
			user.setPassword(null);
		}else{
			user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
		}
		this.updateById(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.removeByIds(Arrays.asList(userId));
	}

	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
		SysUserEntity userEntity = new SysUserEntity();
		userEntity.setPassword(newPassword);
		return this.update(userEntity,
				new QueryWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
	}

	@Override
	public List<EmployeeVo> getAllEmployee() {
		List<EmployeeVo> list = baseMapper.getAllEmployee();
		return list;
	}


	/**
	 * 检查角色是否越权
	 */
	private void checkRole(SysUserEntity user){
		if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
			return;
		}
		//如果不是超级管理员，则需要判断用户的角色是否自己创建
		if(user.getCreateUserId() == Constant.SUPER_ADMIN){
			return ;
		}
		
		//查询用户创建的角色列表
		List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

		//判断是否越权
		if(!roleIdList.containsAll(user.getRoleIdList())){
			throw new RRException("新增用户所选角色，不是本人创建");
		}
	}
}